﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevComponents.DotNetBar;
using System.Xml;
using StuMana.Services;
using System.Threading;
using System.Net.Sockets;
using System.Net;

namespace StuMana.UI
{
    public partial class BookStore : Office2007Form 
    {
        public BookStore()
        {
            InitializeComponent();
        }

        class book_item
        {
            public int _id;
            public string _name;
            public int _price;

            public book_item()
            {
                _id = 0;
                _name = "";
                _price = 0;
            }

            public book_item(int id, string name, int price)
            {
                _id = id;
                _name = name;
                _price = price;
            }
        }

        List<book_item> liBookItem;
        private bool flag = false;
        private bool co = false;
        private Font fontForAll = null;
        private StyleManager managerStyle = new DevComponents.DotNetBar.StyleManager();

        string ProPath;
        byte[] serial_buff = new byte[40];
        Services.SL025M rfid_reader = new Services.SL025M();
        Services.COM connect;
        private Bitmap image;
        private System.Windows.Forms.Timer readTimer;
        private string tag = "";
        private Boolean isSelect = false;
        private Services.student print_std = new Services.student();
        // get size of return byteArray
        private int size;

        public delegate void AsyncCallback(IAsyncResult ar);
        public delegate void AddTolstDiscoveredDevices(object o);

        private UdpState GlobalUDP;

        /// <summary>
        ///  UDP
        /// </summary>
        struct UdpState
        {
            public System.Net.IPEndPoint EP;
            public System.Net.Sockets.UdpClient UDPClient;   
        }

        /// Danh sách các gói tin
        List<Byte[]> liPacketUDP = new List<byte[]>();
        /// <summary>
        /// Thread Receive 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        
        public void ReceivePacket()
        {
            if (btnStart.Text == "Stop")
            {
                while (true)
                {
                    IPEndPoint ep;
                    try
                    {
                        ep = new IPEndPoint(0, 30303);
                        byte[] receiveData = GlobalUDP.UDPClient.Receive(ref ep);
                        if (receiveData.Length > 0)
                        {
                            liPacketUDP.Add(receiveData);
                        }
                    }
                    catch (Exception e)
                    {
                     //   GlobalUDP.UDPClient.Close();
                    }
                    Thread.Sleep(30);
                }
            }
        }

        /// <summary>
        /// Thread Process
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void Process()
        {            
            while (true)
            {
                if (liPacketUDP.Count() > 0)
                {
                    try
                    {
                        byte[] recData = liPacketUDP.ElementAt(0);
                        liPacketUDP.RemoveAt(0);             
                        string ReceiveString = Encoding.ASCII.GetString(recData);
                        ReceiveString = ReceiveString.Replace("\r\n", "\n");
                        serial_buff = FromHex(ReceiveString);
                        tag = get_student_tagID().ToString();
                        gPanelBookStore.Invoke(new AddTolstDiscoveredDevices(show_stdInfo), tag);
                        //MessageBox.Show("Data from Client:" + Encoding.Default.GetString(recData));
                        
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }               
                }
                Thread.Sleep(30);
            }
        }

        Thread thReceive;
        Thread thProcess;

        private void cmdDiscoverDevices_Click(object sender, EventArgs e)
        {
            try
            {
                // Try to send the discovery request message
                byte[] DiscoverMsg = Encoding.ASCII.GetBytes("Discovery: Who is out there?");   
                GlobalUDP.UDPClient.Send(DiscoverMsg, DiscoverMsg.Length, new System.Net.IPEndPoint(System.Net.IPAddress.Parse("255.255.255.255"), 30303));
            }
            catch
            {
                MessageBox.Show("Unable to transmit discovery message.  Check network connectivity and ensure that no other instances of this program are running.", "Error", MessageBoxButtons.OK);
                return;
            }
        }


        public void ReceiveCallback(IAsyncResult ar)
        {
            UdpState MyUDP = (UdpState)ar.AsyncState;
            // Obtain the UDP message body and convert it to a string, with remote IP address attached as well
            if (btnStart.Text == "Stop")
            {
                try
                {
                    Byte[] receiBytes = MyUDP.UDPClient.EndReceive(ar, ref MyUDP.EP);
                    string ReceiveString = Encoding.ASCII.GetString(receiBytes);
                    liPacketUDP.Add(receiBytes);
                    //MessageBox.Show(ReceiveString.ToString() + "1");
                    ReceiveString = ReceiveString.Replace("\r\n", "\n");
                    MyUDP.UDPClient.BeginReceive(ReceiveCallback, MyUDP);
                    serial_buff = FromHex(ReceiveString);
                    tag = get_student_tagID().ToString();
                    gPanelBookStore.Invoke(new AddTolstDiscoveredDevices(show_stdInfo), tag);
                }
                catch (Exception e)
                {
                    //MessageBox.Show(e.Message, "Warning 12");
                }
            }
        }

        public static byte[] FromHex(string hex)
        {
            hex = hex.Replace("-", "");
            byte[] raw = new byte[hex.Length / 2];
            for (int i = 0; i < raw.Length; i++)
            {
                raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
            }
            return raw;
        }
        /*--------------------------------------------------------------*/

        // timer event handler
        private void readTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                rfid_reader.selectCard();
                size = connect.getdata(serial_buff);
                // login
                if (serial_buff[3] != 0x01 && size != 5000 && isSelect == false)
                {
                    readTimer.Enabled = false;
                    // login to tag
                    rfid_reader.LogIn();
                    size = connect.getdata(serial_buff);

                    // ReadData from tag
                    if (serial_buff[3] == 0x02 && size != 5000)
                        rfid_reader.ReadData();
                    else
                    {
                        readTimer.Enabled = true;
                        throw new Exception("Login fail");
                    }
                    size = connect.getdata(serial_buff);

                    //Receive data
                    if (serial_buff[3] == 0x00 && size != 5000)
                    {
                        tag = get_student_tagID().ToString();
                        show_stdInfo(tag);
                        isSelect = true;
                    }
                    else
                    {
                        readTimer.Enabled = true;
                        throw new Exception("Data isn't received");
                    }

                    readTimer.Enabled = true;
                }
                else if (serial_buff[3] == 0x01)
                {
                    isSelect = false;
                }
                else if (size == 5000)
                {
                }

            }
            catch (Exception es)
            {
                string msg = es.Message;
            }
        }

        // change tagID into 
        private Int32 get_student_tagID()
        {
            Byte[] temp_byte = { 0x00, 0x00, 0x00, 0x00 };
            temp_byte[2] = serial_buff[6];
            temp_byte[1] = serial_buff[5];
            temp_byte[0] = serial_buff[4];
            Int32 temstr = BitConverter.ToInt32(temp_byte, 0);
            return temstr;
        }

        public void show_stdInfo(object o)
        {
            string tagID = (string)(o);
            try
            {
                if (print_std.getStdInfo(tagID))
                {
                    // change stt inout in database
                    print_std.change_stt(tagID);
                    //Insert to database the information of check in-out
                    print_std.AddNewActivity();
                    //show info to FORM
                    lblID.Text = print_std.TagID.ToString();
                    lblName.Text = print_std.Name;
                    lblClass.Text = print_std.Class;
                    lblAccount.Text = print_std.Account.ToString();                  
                    ProPath = Environment.CurrentDirectory;
                    ProPath += "\\images\\" + lblID.Text + ".jpg";
                    image = new Bitmap(Image.FromFile(ProPath), new Size(refImage.Width, refImage.Height));
                    refImage.Image = image;
                    txtXPinCode.Enabled = true;
                }
                else
                    resetForm();
            }
            catch (Exception ex)
            {
                string msg = ex.Message;               
                ProPath = Environment.CurrentDirectory;
                ProPath += "\\images\\logo.jpg";
                image = new Bitmap(Image.FromFile(ProPath), new Size(refImage.Width, refImage.Height));
                refImage.Image = image;
            }
        }

        // form reset
        private void resetForm()
        {
            lblID.Text = "None";
            lblName.Text = "None";
            lblClass.Text = "None";
            lblAccount.Text="None";
            ProPath = Environment.CurrentDirectory;
            ProPath += "\\images\\logo.jpg";
            image = new Bitmap(Image.FromFile(ProPath), new Size(refImage.Width, refImage.Height));
            refImage.Image = image;
        }
     
        // Initial COM connecting
        public void InitialConnect(StuMana.Services.COM conn)
        {
            connect = conn;
            rfid_reader.conn = conn.serialPort;
        }

        public static string ByteArrayToString(byte[] ba)
        {
            StringBuilder hex = new StringBuilder(ba.Length * 2);
            foreach (byte b in ba)
                hex.AppendFormat("{0:x2}", b);
            return hex.ToString();
        }
    
        private void btnStart_Click(object sender, EventArgs e)
        {
            if (btnStart.Text == "Start")
            {
                // bat goi tin nhan duoc de hien thi len information 
                try
                {
                    GlobalUDP.UDPClient = new UdpClient();
                    GlobalUDP.EP = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("255.255.255.255"), 30303);
                    System.Net.IPEndPoint BindEP = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 30303);
                    GlobalUDP.UDPClient.Client.Bind(BindEP);
                    // Enable the transmission of broadcast packets without having them be received by ourself
                    GlobalUDP.UDPClient.EnableBroadcast = true;
                    GlobalUDP.UDPClient.MulticastLoopback = false;
                    // Configure ourself to receive discovery responses
                    GlobalUDP.UDPClient.BeginReceive(ReceiveCallback, GlobalUDP);
                    //// broadcast discovery 
                    thReceive = new Thread(new ThreadStart(ReceivePacket));
                    thProcess = new Thread(new ThreadStart(Process));
                    //thread nhận tin bắt đầu 
                    thReceive.Start();
                    //  thread process bắt đầu
                    thProcess.Start();
                    // Transmit the discovery request message                  
                     btnStart.Text = "Stop";
                }
                catch
                {
                    MessageBox.Show("Unable to transmit discovery message.  Check network connectivity and ensure that no other instances of this program are running.", "Error", MessageBoxButtons.OK);
                    return;
                }
            }
            else
            {
                btnStart.Text = "Start";          
                GlobalUDP.UDPClient.Close();            
             //   thReceive.Suspend();
                thReceive.Abort();
                thProcess.Abort();
             //   thProcess.Suspend();            
            }
        }

        public void ReadSetting()
        {
            XmlReader reader = XmlReader.Create("Settings.xml");
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element
                && reader.Name == "font")
                {
                    string name = reader.GetAttribute(0).ToString();
                    string style = reader.GetAttribute(1).ToString();
                    float size = float.Parse(reader.GetAttribute(2).ToString());

                    if (style == "Bold")
                        fontForAll = new System.Drawing.Font(reader.GetAttribute(0).ToString(), size, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                    if (style == "Italic")
                        fontForAll = new System.Drawing.Font(reader.GetAttribute(0).ToString(), size, System.Drawing.FontStyle.Italic, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                    if (style == "Regular")
                        fontForAll = new System.Drawing.Font(reader.GetAttribute(0).ToString(), size, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                    if (style == "Strikeout")
                        fontForAll = new System.Drawing.Font(reader.GetAttribute(0).ToString(), size, System.Drawing.FontStyle.Strikeout, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
                    if (style == "Underline")
                        fontForAll = new System.Drawing.Font(reader.GetAttribute(0).ToString(), size, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(0)));

                    while (reader.NodeType != XmlNodeType.EndElement)
                    {
                        reader.Read();
                        if (reader.Name == "managerstyle" && reader.NodeType == XmlNodeType.Element)
                        {
                            reader.Read();
                            string stylemana = reader.Value.ToString();
                            if (stylemana == "Office2007Blue")
                                managerStyle.ManagerStyle = DevComponents.DotNetBar.eStyle.Office2007Blue;
                            if (stylemana == "Office2007Silver")
                                managerStyle.ManagerStyle = DevComponents.DotNetBar.eStyle.Office2007Silver;
                            if (stylemana == "Office2007Black")
                                managerStyle.ManagerStyle = DevComponents.DotNetBar.eStyle.Office2007Black;
                            if (stylemana == "Windows7Blue")
                                managerStyle.ManagerStyle = DevComponents.DotNetBar.eStyle.Windows7Blue;
                            if (stylemana == "Office2007VistaGlass")
                                managerStyle.ManagerStyle = DevComponents.DotNetBar.eStyle.Office2007VistaGlass;
                            if (stylemana == "Office2010Silver")
                                managerStyle.ManagerStyle = DevComponents.DotNetBar.eStyle.Office2010Silver;
                            if (stylemana == "Office2010Blue")
                                managerStyle.ManagerStyle = DevComponents.DotNetBar.eStyle.Office2010Blue;
                            if (stylemana == "Office2010Black")
                                managerStyle.ManagerStyle = DevComponents.DotNetBar.eStyle.Office2010Black;
                        }
                    }
                }
            }
            reader.Close();
        }

        public void ConfigSetting()
        {
            ReadSetting();
            for (int i = 0; i < Controls[0].Controls.Count; i++)
            {
                if (Controls[0].Controls[i] is LabelX)
                {
                    Controls[0].Controls[i].Font = fontForAll;
                }
            }
            styleManager1 = managerStyle;
        }

        public void LoadBookStoreData(int type)
        {
            lvEDanhSach.Items.Clear();
            ConnectionController control = new ConnectionController();
            control.connection.Open();
            try
            {
                MySql.Data.MySqlClient.MySqlCommand cmd = control.connection.CreateCommand();
                cmd.CommandText = "SELECT ID, Name, Price  FROM bookstore WHERE Type = " + type.ToString();
                MySql.Data.MySqlClient.MySqlDataAdapter adap = new MySql.Data.MySqlClient.MySqlDataAdapter(cmd);
                DataSet ds = new DataSet();
                adap.Fill(ds);
                DataTable dt = new DataTable();
                dt=ds.Tables[0];
                foreach (DataRow r in dt.Rows)
                {
                    string iteStr = "";
                    string nameBookStore = r[1].ToString();
                    if (nameBookStore.Length > 14)
                    {
                        iteStr = nameBookStore.Substring(0, 14) + "... - $" + r[2].ToString();
                    }
                    else
                    {
                        iteStr = r[1].ToString() + "- $" + r[2].ToString();
                    }
                                  
                    ListViewItem item = new ListViewItem(iteStr);                    
                    item.ImageIndex = type - 1; ;
                    for(int i=0; i<dt.Columns.Count;i++)
                    {
                        item.SubItems.Add(r[i].ToString());
                    }
                    lvEDanhSach.Items.Add(item);        
                }    
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (control.connection.State == ConnectionState.Open)
                    control.connection.Clone();
            }
        }

        public void LoadBookStoreTypeData()
        {
            ConnectionController control = new ConnectionController();
            control.connection.Open();
            try
            {
                MySql.Data.MySqlClient.MySqlCommand cmd = control.connection.CreateCommand();
                cmd.CommandText = "SELECT *  FROM bookstore_type ";
                MySql.Data.MySqlClient.MySqlDataAdapter adap = new MySql.Data.MySqlClient.MySqlDataAdapter(cmd);
                DataSet ds = new DataSet();
                adap.Fill(ds);
                cmbBookStore.DataSource = ds.Tables[0].DefaultView;
                cmbBookStore.ValueMember = "ID";
                cmbBookStore.DisplayMember = "Name";
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (control.connection.State == ConnectionState.Open)
                    control.connection.Clone();
            }
        }

        private void BookStore_Load(object sender, EventArgs e)
        {
            ConfigSetting();
            cmbViewLvEDanhSach.SelectedIndex = 2;
            LoadBookStoreTypeData();
            LoadBookStoreData(int.Parse(cmbBookStore.SelectedValue.ToString()));
            liBookItem = new List<book_item>();
            flag = true;
            co = true;
            if (dgvListChoose.Columns.Count > 0)
            {
                int w = dgvListChoose.Size.Width;
                int widthC = ((int)w / 3);
                dgvListChoose.Columns[0].Width = widthC;
                dgvListChoose.Columns[1].Width = widthC;
                dgvListChoose.Columns[2].Width = widthC;
            }
        }

        public void resetAll()
        {
            lblID.Text = "NONE";// "lblID";
            lblName.Text = "NONE";// "lblName";
            lblAccount.Text = "NONE";// "lblAccount";
            lblClass.Text = "NONE";//"lblClass";

            image = StuMana.Properties.Resources.HCMIU;
            refImage.Image = image;

            // reset textbox pincode 
            txtXPinCode.Text = "";
            txtXPinCode.Enabled = false;
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            lblID.Text = "NONE";// "lblID";
            lblName.Text = "NONE";// "lblName";
            lblAccount.Text = "NONE";// "lblAccount";
            lblClass.Text = "NONE";//"lblClass";

            image = StuMana.Properties.Resources.HCMIU;
            refImage.Image = image;

            // reset textbox pincode 
            txtXPinCode.Text = "";
            txtXPinCode.Enabled = false;
        }
     
        private void cmbBookStore_SelectedIndexChanged(object sender, EventArgs e)
        {
            flag = false;
            if (flag == false)
            {
                cmbBookStore.DisplayMember = "Name";
                cmbBookStore.ValueMember = "ID";
                LoadBookStoreData(int.Parse(cmbBookStore.SelectedValue.ToString()));
            }
            flag = true;
        }

        public void BuyInBookStore(int idBookStore, int idStudent)
        {
            ConnectionController control = new ConnectionController();
            control.connection.Open();
            try
            {
                MySql.Data.MySqlClient.MySqlCommand cmd = control.connection.CreateCommand();
                cmd.CommandText = "INSERT INTO Log_BookStore(TagID,ID_BookStore,date)  VALUES(" + idStudent.ToString() + "," + idBookStore.ToString() + ",'" + DateTime.Today.ToString("yyyy/MM/dd") + "')";
                MySql.Data.MySqlClient.MySqlDataAdapter adap = new MySql.Data.MySqlClient.MySqlDataAdapter(cmd);
                cmd.ExecuteNonQuery();
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (control.connection.State == ConnectionState.Open)
                    control.connection.Clone();
            }
        }

        public bool CheckPinCode(string pinCodeStudent)
        {
            bool kq = false;
            if (pinCodeStudent == txtXPinCode.Text)
                kq = true;
            return kq;
        }

        private void btnChoose_Click(object sender, EventArgs e)
        {
            if (lblID.Text == "lblID")
            {
                MessageBoxEx.Show("Student ID not availible", "Warning !!!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            else
            {
                if (lvEDanhSach.SelectedItems.Count>0)
                {
                    for (int i = lvEDanhSach.SelectedItems.Count - 1; i > -1; i--)
                    {
                        int idChoose = int.Parse(lvEDanhSach.SelectedItems[i].SubItems[1].Text.ToString());
                        string nameChoose = lvEDanhSach.SelectedItems[i].SubItems[2].Text.ToString();
                        int priceChoose = int.Parse(lvEDanhSach.SelectedItems[i].SubItems[3].Text.ToString());
                        book_item bookChoose = new book_item(idChoose, nameChoose, priceChoose);
                        liBookItem.Add(bookChoose);
                        dgvListChoose.Rows.Add(idChoose.ToString(), nameChoose.ToString(), priceChoose.ToString());
                    }                               
                }
                else
                    MessageBoxEx.Show("You have not choose", "Warning !!!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }

        private void cmbViewLvEDanhSach_SelectedIndexChanged(object sender, EventArgs e)
        {
            //  0 tile 1 small 2 large
            if (cmbViewLvEDanhSach.SelectedIndex == 0)
            {
                lvEDanhSach.View = System.Windows.Forms.View.Tile;
            }
            else if (cmbViewLvEDanhSach.SelectedIndex == 1)
            {
                lvEDanhSach.View = System.Windows.Forms.View.SmallIcon;
            }
            else if (cmbViewLvEDanhSach.SelectedIndex == 2)
            {
                lvEDanhSach.View = System.Windows.Forms.View.LargeIcon;
            }
        }

        private void BookStore_FormClosed(object sender, FormClosedEventArgs e)
        {
            Environment.Exit(Environment.ExitCode);
            Application.ExitThread();
            Application.Exit();
        }

        private void BookStore_FormClosing(object sender, FormClosingEventArgs e)
        {
            Environment.Exit(Environment.ExitCode);
            Application.ExitThread();
            Application.Exit();
        }

        private void BookStore_Resize(object sender, EventArgs e)
        {
            if (dgvListChoose.Columns.Count > 0)
            {
                int w = dgvListChoose.Size.Width;
                int widthC = ((int)w / dgvListChoose.Columns.Count);
                {
                    for (int i = 0; i < dgvListChoose.Columns.Count; i++)
                    {
                        dgvListChoose.Columns[i].Width = widthC;
                    }                
                }
            }
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            if (dgvListChoose.SelectedRows.Count > 0)
            {
                for (int i = 0; i < dgvListChoose.SelectedRows.Count; i++)
                {
                    int index = dgvListChoose.SelectedRows[i].Index;
                    liBookItem.RemoveAt(index);
                }
                Remove();
            }
        }

        // cap nhat list book item sau khi xoa
        public void Remove()
        {
            for (int i = dgvListChoose.Rows.Count - 1; i > -1; i--)
            {
                dgvListChoose.Rows.RemoveAt(i);
            }
            for (int i = 0; i < liBookItem.Count; i++)
            {
                book_item bookChoose = (book_item)liBookItem[i];
                dgvListChoose.Rows.Add(bookChoose._id.ToString(), bookChoose._name, bookChoose._price.ToString());
            }
        }

        private void btnThanhToan_Click(object sender, EventArgs e)
        {
            if (dgvListChoose.Rows.Count > 0)
            {
                int tongtien = 0;
                for (int i = 0; i < liBookItem.Count; i++)
                {
                    tongtien += liBookItem[i]._price;
                }
                DialogResult diaResult = MessageBoxEx.Show("You must pay " + tongtien.ToString() + " VND", "Information", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
                if (diaResult == DialogResult.Yes)
                {
                    int account = int.Parse(lblAccount.Text.ToString());
                    if (tongtien > account)
                    {
                        MessageBoxEx.Show("You have no money for list choose", "Warning  !!!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    }
                    else
                    {
                        if (CheckPinCode(print_std.PinCode))
                        {
                            account = account - tongtien;
                            lblAccount.Text = account.ToString();
                            print_std.Account = account;
                            print_std.update_account(lblID.Text);
                            for (int i = 0; i < liBookItem.Count; i++)
                            {
                                BuyInBookStore(liBookItem[i]._id, int.Parse(lblID.Text.ToString()));
                            }
                            liBookItem.Clear();
                            Remove();
                            resetAll();
                        }
                        else
                        {
                            MessageBoxEx.Show("Wrong PINCODE \n Please Check your pincode  ", "Error  !!!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return;
                        }
                    }
                }
            }
            else
            {
                MessageBoxEx.Show("List choose is empty", "Warning !!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
    }
}
